/**
 *
 */

import { isArray, isObject, isString } from 'fc-cli-core'
import FCRuleFactor from './FCRuleFactor'
import FCRuleTableRecord, { dataIndexBuilder } from './FCRuleTableRecord'
import FCRuleTableColumn, { COLUMN_TYPE } from './FCRuleTableColumn'

class FCRuleTableInstance {
  /* properties */

  key // 规则表 key
  colConditions = [] // 列条件因子
  rowConditions = [] // 行条件因子
  colResults = [] // 列结果因子
  cellResults = [] // 单元格结果因子
  columns = [] // 列对象数组
  records = [] // 行对象数组

  // todo: 以下可能不再需要
  //
  changeStub = '' //表格编辑状态
  mergedColumns = []
  _newcolumns = []
  // todo: 以上可能不再需要

  /* getters */

  // 获取行因子 code 数组
  _rowFactorCodes
  get rowFactorCodes() {
    if (!this._rowFactorCodes) {
      this._rowFactorCodes = this.rowConditions.map((factor) => factor.code)
    }
    return this._rowFactorCodes
  }
  set rowFactorCodes(_rowFactorCodes) {
    this._rowFactorCodes = _rowFactorCodes
  }
  //

  // 获取列结果 code 数组
  _colResultCodes
  get colResultCodes() {
    if (!this._colResultCodes) {
      this._colResultCodes = this.colResults.map((factor) => factor.code)
    }
    return this._colResultCodes
  }
  set colResultCodes(_colResultCodes) {
    this._colResultCodes = _colResultCodes
  }

  // 获取所有因子
  get factors() {
    return [...this.colConditions, ...this.rowConditions, ...this.colResults, ...this.cellResults]
  }

  // 默认只有一个 cellResult Factor
  get defaultCellResultFactor() {
    return this.cellResults.length > 0 ? this.cellResults[0] : undefined
  }

  /* static methods */

  // 返回一个 FCRuleTableInstance 实例
  static createTable() {
    return new FCRuleTableInstance()
  }

  // 生成 table.key
  static #tableIndex = 1
  static createNewTableKey() {
    return `t:${this.#tableIndex++}`
  }

  /* lifecycle methods */

  constructor() {
    this.key = FCRuleTableInstance.createNewTableKey()
  }

  // 初始化时加载数据，会先清空所有数据
  // 入参为 vue 组件的 props
  initWithDatas({ colConditions = [], rowConditions = [], results = [], colResults = [], cellResults = [], rules, mergedColumns = [] } = {}) {
    // 清空所有数据
    this.clearDatas()

    // 初始化条件因子
    this.colConditions = this.buildFactors(colConditions)
    // 初始化条件因子的代码
    // this.colConditionCodes = this.colConditions.map((factor) => factor.code)

    this.rowConditions = this.buildFactors(rowConditions)
    // 初始化条件因子的代码
    // this.rowConditionCodes = this.rowConditions.map((factor) => factor.code)

    // 根据 rowConditions 确定 results 是 cellResults 还是 colResults
    if (rowConditions.length > 0) {
      cellResults = [...cellResults, ...results]
    } else {
      colResults = [...colResults, ...results]
    }

    this.cellResults = this.buildFactors(cellResults)
    this.colResults = this.buildFactors(colResults)

    // 初始化 columns
    this.columns = this.buildColumns({ colFactors: this.colConditions, rowFactors: this.rowConditions, colResults: this.colResults })

    // 初始化 records
    console.log('>>>> rules:', rules);
    this.records = this.initRecordsWithDatas(rules)

    ////
    // this.mergedColumns = this.buildMergedColumns(mergedColumns)
  }

  // 更新因子
  updateFactors({ colConditions, rowConditions, results, colResults, cellResults } = {}) {
    console.log('now update factors')

    if (colConditions) {
      this.colConditions = this.buildFactors(colConditions)
    }

    if (rowConditions) {
      this.rowConditions = this.buildFactors(rowConditions)
    }

    if (this.rowConditions.length > 0) {
      cellResults = results
    } else {
      colResults = results
    }

    if (cellResults) {
      this.cellResults = this.buildFactors(cellResults)
    }

    if (colResults) {
      this.colResults = this.buildFactors(colResults)
    }

    // 初始化 columns
    this.columns = this.buildColumns({ colFactors: this.colConditions, rowFactors: this.rowConditions, colResults: this.colResults })

    // this.rowConditions = this.buildFactors(rowConditions)

    // 初始化 records
    this.records = this.updateRecords(this.records)

    console.log('this.records:', this.records)
  }

  updateRecords(records) {
    // const ruleDatas = records.map((record) => record.getRuleData())

    let ruleDatas = []
    records.forEach((record) => {
      ruleDatas = [...ruleDatas, ...record.getRuleDatas()]
    })

    return this.initRecordsWithDatas(ruleDatas)
  }

  /* public methods */

  // columns for table
  buildTableColumns() {
    return this.columns.map((column) => column.buildTableColumn())
  }

  // dataSource for table
  buildTableDataSource() {
    return this.records.map((record) => record.buildTableDataSource())
  }

  // 获取因子数据
  getFactor(code) {
    return this.factors.find((factor) => factor.code === code)
  }

  // // 修改因子
  // setFactorTitle(code, title) {
  //   const factor = this.getFactor(code)
  //   if (factor) {
  //     // todo: 需要通知界面刷新
  //     factor.title = title
  //   }
  // }

  // // 高亮cell
  // highlightValue(rule, factor) {}

  // highlightTitle(code) {}

  // highlightMatchedValues({ condition, options, factor } = {}) {
  //   // todo:
  // }

  // 合并表头
  mergeColumns({ title, dataIndices } = {}) {
    console.log('mergeColumns:', title, dataIndices)
    this.mergedColumns.push({ title, dataIndices })
    this.changeStub = 'column'
  }

  // 拆分表头
  splitColumn(dataIndexs) {
    this.mergedColumns = this.mergedColumns.filter((item) => item.dataIndices.toString() !== dataIndexs.toString())
    console.log('splitColumn:', dataIndexs, this.mergedColumns)
    this.changeStub = 'column'
  }

  // 获取被合并的 column dataIndex
  getMergedColumns(dataIndex) {
    console.log('get merged columns:', dataIndex)
    return []
  }

  // 通过 dataIndex 查询 title 的 valuePath
  getValuesWithDataIndex(dataIndex) {
    console.log('getValuesWithDataIndex:', dataIndex)
    return {}
  }

  getRecordAt(index) {
    return this.records[index]
  }

  doUpdateTable() {
    console.log('now do it....')
  }

  /* private methods */

  // 生成 factor.key
  #factorIndex = 1
  createNewFactorKey() {
    return `${this.key}-f:${this.#factorIndex++}`
  }

  // 生成 record.key
  #recordIndex = 1
  createNewRecordKey() {
    return `${this.key}-r:${this.#recordIndex++}`
  }

  // 清空所有数据，在 loadDatas 之前调用，确保是初始化
  clearDatas() {
    this.colConditions = []
    this.rowConditions = []
    this.rowFactorCodes = null
    this.colResults = []
    this.colResultCodes = null
    this.cellResults = []
    this.columns = []
    this.records = []
  }

  // 构造因子
  buildFactors(factorDatas = []) {
    return factorDatas.map(
      ({ code, title, dataType, options, render, parser, mergeData, linkProps } = {}) =>
        new FCRuleFactor({
          key: this.createNewFactorKey(),
          code,
          title,
          options,
          dataType,
          mergeData,
          render,
          parser,
          linkProps,
        })
    )
  }

  // 创建 columns
  buildColumns({ colFactors, rowFactors, colResults }) {
    // 列条件因子对应的 column
    const colFactorColumns = this.buildColumnsWithColFactors(colFactors, COLUMN_TYPE.colCondition)

    // 行条件因子对应的 column
    const rowFactorColumns = this.buildColumnsWithRowFactors(rowFactors)

    // 列结果对应的 column
    const colResultColumns = this.buildColumnsWithColFactors(colResults, COLUMN_TYPE.colResult)

    return [...colFactorColumns, ...rowFactorColumns, ...colResultColumns]
  }

  // 创建列因子对应的表头 columns 数组
  buildColumnsWithColFactors(factors, type) {
    return factors.map(
      (factor) =>
        new FCRuleTableColumn({
          type,
          title: factor.title,
          dataIndex: factor.code,
        })
    )
  }

  // 根据 this.rowFactors 构建表头 columns 树型结构
  buildColumnsWithRowFactors(factors = [], depth = 0, valuePath = []) {
    if (depth >= factors.length) {
      return []
    }

    const currentFactor = factors[depth]

    // 遍历 factor.options
    return currentFactor.options.map((option) => {
      const newValue = option.value
      const currentValuePath = [...valuePath, newValue]
      const dataIndex = dataIndexBuilder(currentValuePath)

      let children
      if (depth < factors.length - 1) {
        children = this.buildColumnsWithRowFactors(factors, depth + 1, currentValuePath)
      }

      return new FCRuleTableColumn({
        type: COLUMN_TYPE.rowCondition,
        title: option.label,
        valuePath: currentValuePath,
        dataIndex,
        children,
      })
    })
  }

  // 初始化 records，只有 init 的时候调用
  initRecordsWithDatas(ruleDatas = []) {
    const records = []

    const tmpRecordMap = {} // 临时存放 colFactorKey: record ，用于查询 record 是否已创建
    for (const ruleData of ruleDatas) {
      const colFactorKey = this.getColFactorKeyWithRuleData(ruleData)
      const { record, isNew } = this.getOrCreateRecordWithColFactorKey(colFactorKey, tmpRecordMap)
      record.addRuleData(ruleData)

      if (isNew) {
        records.push(record)
      }
    }

    return records
  }

  // 根据 rule data 创建 col factor key
  getColFactorKeyWithRuleData(ruleData) {
    const colFactorValues = this.colConditions.map((factor) => ruleData[factor.code])
    return colFactorValues.join('-')
  }

  // 获取或创建 record
  getOrCreateRecordWithColFactorKey(colFactorKey = '', recordMap = {}) {
    let record = recordMap[colFactorKey]
    let isNew = false

    if (!record) {
      record = new FCRuleTableRecord({
        key: this.createNewRecordKey(),
        table: this,
      })
      recordMap[colFactorKey] = record
      isNew = true
    }

    return { record, isNew }
  }

  // end of clean cold
  /////////

  buildDataIndexWithValues(value) {
    if (isArray(value)) {
      return value.join('-')
    }
  }

  // 根据父组件寻找
  findColumnByDataIndex(columns, dataIndex) {
    for (const column of columns) {
      if (column.dataIndex === dataIndex) {
        return column.children
      }
      if (column.children) {
        const res = this.findColumnByDataIndex(column.children, dataIndex)
        if (res) {
          return res
        }
      }
    }
  }

  // 获取同一父组件下的option
  getOptionsWithParent(parent) {
    const findOptions = this.findColumnByDataIndex(this.columns, parent)
    console.log('>>> findOptions is:', this.columns)
    return findOptions?.map((column) => ({
      title: column.title,
      dataIndex: column.dataIndex,
      key: column.dataIndex,
    }))
  }

  buildMergedColumns(mergeColumns) {
    return mergeColumns.map((mergeColumn) => {
      const { title, values } = mergeColumn
      const dataIndices = values.map((value) => this.buildDataIndexWithValues(Object.values(value)))
      return {
        title,
        dataIndices,
      }
    })
  }

  // buildRowConditionDataIndexDatas() {
  //   const results = []
  //   this.buildDataIndexData({ factors: this.rowConditions, results })
  //   return results
  // }

  // 递归，根据当前 rowConditions 合并 dataIndex 相关数据
  // buildDataIndexData({ factors, factorIndex = 0, valuePath = [], results = {} } = {}) {
  //   const currentFactor = factors[factorIndex] || {}
  //   const { options } = currentFactor
  //   if (!isArray(options)) {
  //     return
  //   }

  //   options.forEach((option) => {
  //     // 增加当前 option 的 value
  //     valuePath.push(option.value)

  //     // 如果已经是最后一个了，递归底，需要返回
  //     if (factorIndex === factors.length - 1) {
  //       const values = [...valuePath]
  //       const dataIndex = dataIndexBuilder(values)
  //       results[dataIndex] = { values }
  //       // results.push([...valuePath])
  //       valuePath.pop()
  //       return
  //     }
  //   })
  // }

  // // 在columns中匹配valuePath相同的就删除
  // matchValuePath(columns, valuePaths) {
  //   return columns?.filter((column, index) => {
  //     if (column.children) {
  //       column.children = this.matchValuePath(column.children, valuePaths)
  //     }
  //     const find = valuePaths.find((item) => item.dataIndices.some((dataIndice, index) => dataIndice === column.dataIndex && index === 0))
  //     if (find) {
  //       column.title = find.title
  //     }
  //     if (!valuePaths.some((item) => item.dataIndices.some((dataIndice, index) => dataIndice === column.dataIndex && index !== 0))) {
  //       return column
  //     }
  //   })
  // }

  // clearNotification() {
  //   this.changeStub = ''
  // }
}

export default FCRuleTableInstance
